package com.dungeon.game;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

import android.content.Context;
import android.util.Log;

import com.dungeon.game.Constants.Character_action_code;
import com.dungeon.game.Constants.Class_code;
import com.dungeon.game.Constants.Equipment_type_code;
import com.dungeon.game.Constants.Position_code;
import com.dungeon.game.Constants.Potion_type;
import com.dungeon.game.Constants.Scenario_code;

public class Campaignstate {

		static ArrayList<Charsheet> chars;
		static Integer gold;
		static ArrayList<Integer> current_party;
		static Boolean mute;
		static Scenario mission_chosen;
		static ArrayList<Item> items_owned;
		static HashMap<String,Position_code> char_name_to_favorite_position;
		static ArrayList<Recruit> available_recruits;

		static Item_factory i;
		static Monster_action_factory ma;
		static Character_action_factory ca;

		static Random rand;

		static Integer trips, successes;
		static Double clock_elapsed;
		static ArrayList<Scenario_code> victories;
		static Integer rebuilds;
		static Integer difficulty_level; // 1 to 3

		{init();}

		static void prep(){
			chars = new ArrayList<Charsheet>();
			current_party = new ArrayList<Integer>();
			i = new Item_factory();
			ma = new Monster_action_factory();
			ca = new Character_action_factory();
			mission_chosen = null;
			items_owned = new ArrayList<Item>();
			available_recruits = new ArrayList<Recruit>();
			char_name_to_favorite_position = new HashMap<String,Position_code>();
			rand = new Random();
		}
		
		static void init(){
			prep();
			difficulty_level = 1;
			trips = 0;
			successes = 0;
			clock_elapsed = 0.0;
			victories = new ArrayList<Scenario_code>();
			gold = 30;
			rebuilds = 0;
			mute = false;
			/* Don't change the genesis text without searching for it in CharsheetDialog */
			chars.add(new Charsheet(Class_code.C_WARRIOR, "warrior_1","Thrax",    2, 4,4,5,3,3,1,
					Arrays.asList(Character_action_code.CA_BLOCK,Character_action_code.CA_DEFLECT,Character_action_code.CA_BASH,Character_action_code.CA_RETRENCH),new ArrayList<Character_action_code>(),
					Arrays.asList(Potion_type.POT_SMALLHEAL,Potion_type.POT_SMALLHEAL),
					Equipment_type_code.E_LEATHER_CUIRASS,Equipment_type_code.E_SPEAR,null,null,
					null,null,null,"Has been with you since the beginning of the game."));
			chars.add(new Charsheet(Class_code.C_ROGUE,   "rogue_2",  "Ascia",    2, 4,4,4,2,3,3,
					Arrays.asList(Character_action_code.CA_PICK_LOCKS,Character_action_code.CA_FIND_TRAPS,Character_action_code.CA_WEAKEN,Character_action_code.CA_SNIPE),new ArrayList<Character_action_code>(),
					new ArrayList<Potion_type>(),
					Equipment_type_code.E_CLOAK,Equipment_type_code.E_DAGGER,Equipment_type_code.E_BUCKLER,Equipment_type_code.E_JAVELINS,
					null,null,null,"Has been with you since the beginning of the game."));
			chars.add(new Charsheet(Class_code.C_PRIEST,  "priest_2", "Gyoll",    2, 3,3,5,3,5,1,
					Arrays.asList(Character_action_code.CA_CURE_POISON,Character_action_code.CA_HEALING,Character_action_code.CA_SACRIFICE),new ArrayList<Character_action_code>(),
					Arrays.asList(Potion_type.POT_BAR_PRIEST,Potion_type.POT_BAR_PRIEST),
					Equipment_type_code.E_TUNIC,Equipment_type_code.E_MACE,null,null,
					null,null,null,"Has been with you since the beginning of the game."));
			chars.add(new Charsheet(Class_code.C_MAGE,    "wizard_3",   "Saltus",   2, 3,6,3,1,6,1,
					Arrays.asList(Character_action_code.CA_SPARK,Character_action_code.CA_COUNTER_FEAR),new ArrayList<Character_action_code>(),
					new ArrayList<Potion_type>(),
					Equipment_type_code.E_CLOAK,Equipment_type_code.E_STAFF,null,Equipment_type_code.E_PRENTICE_WAND,
					null,null,null,"Has been with you since the beginning of the game."));
			current_party.add(0);
			current_party.add(1);
			current_party.add(2);
			current_party.add(3);
			available_recruits.add(new Recruit(Class_code.C_WARRIOR, "warrior_3", 40, "Matachin", 2, 20, "strength", 5, 0, 0.0, "An old friend of your first characters."));
		}

		static List<Charsheet> get_party(){
			ArrayList cs = new ArrayList();
			for (int i : current_party)
				cs.add(chars.get(i));
			return cs;
		}
		
		static int max_char_level(){
			int i = 0;
			for (Charsheet cs : chars){
				if (cs.level > i) i=cs.level;
			}
			return i;
		}
		
		static void add_recruit(Class_code _class_code, String _image, int _gold_cost, String _name, int _level, int _points, String _fixed_stat, int _fixed_stat_value, int _trips_when_first_available, double _clock_when_first_available, String _genesis){
			available_recruits.add(new Recruit(_class_code, _image, _gold_cost, _name, _level, _points, _fixed_stat, _fixed_stat_value, _trips_when_first_available, _clock_when_first_available, _genesis));
		}
		
	    static boolean owns_item(Equipment_type_code e){
	    	Item this_item = i.make_item(e);
	    	for (Charsheet cs : chars){
	    		if (cs.melee_weapon!=null && cs.melee_weapon.name().equals(this_item.name())) return true;
	    		if (cs.missile_weapon!=null && cs.missile_weapon.name().equals(this_item.name())) return true;
	    		if (cs.offhand!=null && cs.offhand.name().equals(this_item.name())) return true;
	    		if (cs.armor!=null && cs.armor.name().equals(this_item.name())) return true;
	    		if (cs.trinkets.size()>0 && cs.trinkets.get(0).name().equals(this_item.name())) return true;
	    		if (cs.trinkets.size()>1 && cs.trinkets.get(1).name().equals(this_item.name())) return true;
	    		if (cs.trinkets.size()>2 && cs.trinkets.get(2).name().equals(this_item.name())) return true;
	    		if (cs.trinkets.size()>3 && cs.trinkets.get(3).name().equals(this_item.name())) return true;
	    	}
	    	for (Item ii : items_owned){
	    		if (ii.name().equals(this_item.name())) return true;
	    	}
	    	return false;
	    }

		static boolean dump(Context context, String filename){
			try {
		        FileOutputStream fileOut = context.openFileOutput(filename, Context.MODE_PRIVATE);
				// File file = new File(filename);
				// FileOutputStream fileOut = new FileOutputStream("/mnt/sdcard/demo.demo/"+file);
		        ObjectOutputStream out = new ObjectOutputStream(fileOut);
		        out.writeObject(chars);
		        out.writeObject(gold);
		        out.writeObject(current_party);
		        out.writeObject(mute);
		        out.writeObject(items_owned);
		        out.writeObject(char_name_to_favorite_position);
		        out.writeObject(available_recruits);
		        out.writeObject(trips);
		        out.writeObject(successes);
		        out.writeObject(victories);
		        out.writeObject(clock_elapsed);
		        out.writeObject(rebuilds);
		        out.writeObject(difficulty_level);
		        out.close();
		        fileOut.close();
		        return true;
			} catch (FileNotFoundException ex) {
	    	    Log.e("Demo","crapped110");
	            return false;
	        } catch (IOException ex) {
	     	    Log.e("Demo","crapped111");
	      	    ex.printStackTrace();
	            return false;
	        } 	        
		}

		static boolean load(Context context, String filename){
		    try{
	           FileInputStream fileIn = context.openFileInput(filename);
	           ObjectInputStream in = new ObjectInputStream (fileIn);
	           chars = (ArrayList<Charsheet>)in.readObject();
	           gold = (Integer)in.readObject();
	           current_party = (ArrayList<Integer>)in.readObject();
	           mute = (Boolean)in.readObject();
	           items_owned = (ArrayList<Item>)in.readObject();
			   char_name_to_favorite_position = (HashMap<String,Position_code>)in.readObject();
	           available_recruits = (ArrayList<Recruit>)in.readObject();
	           trips = (Integer)in.readObject();
	           successes = (Integer)in.readObject();
	           victories = (ArrayList<Scenario_code>)in.readObject();
	           clock_elapsed = (Double)in.readObject();
	           rebuilds = (Integer)in.readObject();
	           difficulty_level = (Integer)in.readObject();
			   i = new Item_factory();
			   ma = new Monster_action_factory();
			   ca = new Character_action_factory();
			   rand = new Random();
			   in.close();
	           fileIn.close();
	           return true;
	        } catch (FileNotFoundException ex) {
	     	   Log.e("Demo","crapped112");
	    	   return false;
	        } catch (IOException ex) {
	    	   Log.e("Demo","crapped113");
	    	   Log.e("Demo","exception", ex);
	    	   return false;
	        } catch (ClassNotFoundException ex) {
	    	   Log.e("Demo","crapped114");
	    	   return false;
    	   } 
		}

		static int randint(int a,int b){
			// inclusive
			return rand.nextInt(b-a+1)+a;
		}
		// or use Campaignstate.rand.nextDouble()

		static boolean one_in(int x){
		    if (x<=0){
		        return true;
		    } else {
		        return randint(1,x)==1;
		    }
		}
}

class Recruit implements Serializable {
	private static final long serialVersionUID = -4839631560436950794L;

	Class_code class_code;
	String image, name, fixed_stat;
	int gold_cost, points, fixed_stat_value, level;
	int trips_when_first_available;
	double clock_when_first_available;
	String genesis;

	public Recruit(Class_code _class_code, String _image, int _gold_cost, String _name, int _level, int _points, String _fixed_stat, int _fixed_stat_value, int _trips_when_first_available, double _clock_when_first_available, String _genesis){
		class_code = _class_code;
		image = _image;
		gold_cost = _gold_cost;
		name = _name;
		points = _points;
		level = _level;
		fixed_stat = _fixed_stat;
		fixed_stat_value = _fixed_stat_value;
		trips_when_first_available = _trips_when_first_available;
		clock_when_first_available = _clock_when_first_available;
		genesis = _genesis;
	}
	
	int current_gold_cost(){
		boolean carouse=false;
		boolean inspiring=false;
		for (Charsheet cs : Campaignstate.chars){
			if (cs.master_action_codes.contains(Character_action_code.CA_CAROUSE)) carouse=true;
			if (cs.master_action_codes.contains(Character_action_code.CA_INSPIRING)) inspiring=true;
		}
		double cost = gold_cost;
		if (carouse) cost = 0.8*cost;
		if (inspiring) cost = 0.8*cost;
		return (int)Math.ceil(cost);
	}
}


